package com.xinyue.auto;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;

import com.xinyue.auto.bean.Entity;
import com.xinyue.auto.bean.Page;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 根据数据和模板创建代码文件
 */
public class CodeBuilder implements BuildParam{
	//模板编码
	private static final String ENCODE = "UTF-8";
	//Java文件后缀名
	private static final String JAVA = ".java";
	//Jsp文件后缀名
	private static final String JSP = ".jsp";

	//文件根路径
	private String codeRoot;
	//页面根路径
	private String pageRoot;
	
	public CodeBuilder(String codeRoot, String pageRoot) {
		this.codeRoot = codeRoot;
		this.pageRoot = pageRoot;
	}
	
	/**
	 * 创建Java代码
	 * @param cfg
	 * @param rootDatas
	 * @throws TemplateException 
	 * @throws IOException 
	 */
	public void buildCodeFile(Configuration cfg, List<Entity> entites) throws IOException, TemplateException {
		for (Entity en : entites) {
			//创建JavaBean文件
			createFile(en, cfg.getTemplate(BEANTEMP), getCodeFile(en.getBasePkg(), en.getName(), BEAN_));
			//创建DAO接口文件
			createFile(en, cfg.getTemplate(DAOTEMP), getCodeFile(en.getBasePkg(), en.getName(), DAO_));
			//创建DAO接口实现文件
			createFile(en, cfg.getTemplate(DAOIMPLTEMP), getCodeFile(en.getBasePkg(), en.getName(), DAOIMPL_));
			
			if(en.isNewService()) {
				//创建SERVICE接口文件
				createFile4Exist(en, cfg.getTemplate(SERVICETEMP), getCodeFile(en.getBasePkg(), en.getName(), SERVICE_));
				//创建SERVICE接口实现文件
				createFile4Exist(en, cfg.getTemplate(SERVICEIMPLTEMP), getCodeFile(en.getBasePkg(), en.getName(), SERVICEIMPL_));
			}
			
			if(en.isNewController()) {
				//创建CONTROLLER文件
				createFile4Exist(en, cfg.getTemplate(CONTROLLERTEMP), getCodeFile(en.getBasePkg(), en.getName(), CONTROLLER_));
			}
			
			//创建页面JSP文件
			if(en.getPage() != null) {
				Page p = en.getPage();
				if(p.isIndex()) {
					createFile4Exist(en, cfg.getTemplate(p.getIndexTemp()), getPageFile(p.getPagePath(), p.getIndexName()));
				}
				if(p.isBuild()) {
					createFile4Exist(en, cfg.getTemplate(p.getBuildTemp()), getPageFile(p.getPagePath(), p.getBuildName()));
				}
				if(p.isLook()) {
					createFile4Exist(en, cfg.getTemplate(p.getLookTemp()), getPageFile(p.getPagePath(), p.getLookName()));
				}
			}
		}
	}
	
	
	/**
	 * 调用对应构建器，创建代码文件
	 * @param filePath 文件路径
	 * @param en 数据
	 * @throws IOException 
	 * @throws TemplateException 
	 */
	private void createFile(Entity en, Template temp, File file) throws IOException, TemplateException {
		//如果文件不存在，则创建新文件。
		if(!file.exists()) {
			file.getParentFile().mkdirs();
			file.createNewFile();
		}
		
		//创建输出流并设置编码
		Writer out = new OutputStreamWriter(new FileOutputStream(file), ENCODE);
		temp.process(en, out);
		out.flush();
		out.close();
	}
	
	/**
	 * 调用对应构建器，创建代码文件
	 * 如果文件存在，则不创建该文件
	 * @param filePath 文件路径
	 * @param root 数据
	 * @throws IOException 
	 * @throws TemplateException 
	 */
	private void createFile4Exist(Entity en, Template temp, File file) throws IOException, TemplateException {
		//如果文件不存在，则不做处理
		if(!file.exists()) {
			file.getParentFile().mkdirs();
			file.createNewFile();
			
			//创建输出流并设置编码
			Writer out = new OutputStreamWriter(new FileOutputStream(file), ENCODE);
			temp.process(en, out);
			out.flush();
			out.close();
		}
	}
	
	/**
	 * 获取Java代码文件夹
	 * @param basePkg
	 * @param name
	 * @param type
	 * @return
	 */
	private File getCodeFile(String basePkg, String name, int type) {
		String path = basePkg.replace(".", "/");

		if(type == BEAN_) {
			path += BEAN_P + name;
		}else if(type == DAO_) {
			path += DAO_P + name + DAO_O;
		}else if(type == DAOIMPL_) {
			path += DAOIMPL_P + name + DAOIMPL_O;
		}else if(type == SERVICE_) {
			path += SERVICE_P + name + SERVICE_O;
		}else if(type == SERVICEIMPL_) {
			path += SERVICEIMPL_P + name + SERVICEIMPL_O;
		}else if(type == CONTROLLER_) {
			path += CONTROLLER_P + name + CONTROLLER_O;
		}
		
		File file = new File(codeRoot + "/" + path + JAVA);
		
		return file;
	}
	
	/**
	 * 获得页面文件
	 * @param pagePkg
	 * @param name
	 * @return
	 */
	private File getPageFile(String pagePkg, String name) {
		String path = pagePkg.replace(".", "/");
		File file = new File(pageRoot + path + "/" + name + JSP);
		
		return file;
	}
}
